package g

import "fmt"

const (
	SUCCESS = 0   // 成功业务代码
	FAIL    = 500 // 失败业务代码
)

// 自定义业务 error 类型
type Result struct {
	code int
	msg  string
}

func (e Result) Code() int {
	return e.code
}
func (e Result) Msg() string {
	return e.msg
}

var (
	_codes    = map[int]struct{}{}   // 注册过的错误码集合，防止重复
	_messages = make(map[int]string) // 错误码对应的错误信息
)

// 注册一个响应码，不允许重复注册
func RegisterResult(code int, msg string) Result {
	if _, ok := _codes[code]; ok {
		panic(fmt.Sprintf("错误码 %d 已经存在，请更换一个", code))
	}
	if msg == "" {
		panic("错误码信息不能为空")
	}

	_codes[code] = struct{}{}
	_messages[code] = msg

	return Result{code, msg}
}

func GetMsg(code int) string {
	return _messages[code]
}

var (
	OkResult   = RegisterResult(SUCCESS, "OK")
	FailResult = RegisterResult(FAIL, "FAIL")
)

var (
	ErrRequest  = RegisterResult(9001, "请求参数格式错误")
	ErrDbOp     = RegisterResult(9004, "数据库操作错误")
	ErrRedisOp  = RegisterResult(9005, "Redis操作错误")
	ErrUserAuth = RegisterResult(9006, "用户认证异常")

	ErrPassword     = RegisterResult(1002, "密码错误")
	ErrUserNotExist = RegisterResult(1003, "用户不存在")
	ErrOldPassword  = RegisterResult(1010, "旧密码错误")

	ErrTokenNotExist    = RegisterResult(1201, "Token 不存在,请重新登陆")
	ErrTokenRuntime     = RegisterResult(1202, "Token 已过期,请重新登陆")
	ErrTokenWrong       = RegisterResult(1203, "Token 不正确,请重新登陆")
	ErrTokenType        = RegisterResult(1204, "Token 格式错误,请重新登陆")
	ErrTokenCreate      = RegisterResult(1205, "Token 创建失败,请重新登陆")
	ErrPermission       = RegisterResult(1206, "权限不足")
	ErrForceOffline     = RegisterResult(1207, "您已被强制下线")
	ErrForceOfflineSelf = RegisterResult(1208, "不能强制下线自己")

	ErrFileUpload  = RegisterResult(9100, "文件上传失败")
	ErrFileReceive = RegisterResult(9101, "文件接收失败")

	ErrTagHasArt  = RegisterResult(4003, "标签下存在文章,无法删除")
	ErrCateHasArt = RegisterResult(3003, "分类下存在文章,无法删除")

	ErrResourceNotExist    = RegisterResult(6002, "该资源不存在")
	ErrResourceUsedByRole  = RegisterResult(6003, "该资源正在被角色使用，无法删除")
	ErrResourceHasChildren = RegisterResult(6004, "该资源下存在子资源，无法删除")
	ErrMenuNotExist        = RegisterResult(6006, "该菜单不存在")
	ErrMenuUsedByRole      = RegisterResult(6007, "该菜单正在被角色使用，无法删除")
	ErrMenuHasChildren     = RegisterResult(6008, "该菜单下存在子菜单，无法删除")

	ErrMailSend         = RegisterResult(1011, "邮件发送失败")
	ErrMailHasSend      = RegisterResult(1012, "已朝该邮箱发送验证码（有效期 15 分钟），请检查回收站")
	ErrVerificationCode = RegisterResult(1013, "验证码错误")
)
